package com.resys.service.impl;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.resys.entity.dto.MtroomDto;
import com.resys.entity.dto.OrderDto;
import com.resys.entity.po.Reservationorder;
import com.resys.entity.query.ReservationorderQuery;
import com.resys.entity.vo.StatusVo;
import com.resys.exception.BusinessException;
import com.resys.mappers.ReservationorderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.resys.entity.enums.PageSize;
import com.resys.entity.query.MeetingroomQuery;
import com.resys.entity.po.Meetingroom;
import com.resys.entity.vo.PaginationResultVO;
import com.resys.entity.query.SimplePage;
import com.resys.mappers.MeetingroomMapper;
import com.resys.service.MeetingroomService;
import com.resys.utils.StringTools;


/**
 *  业务接口实现
 */
@Service("meetingroomService")
public class MeetingroomServiceImpl implements MeetingroomService {

	@Resource
	private MeetingroomMapper<Meetingroom, MeetingroomQuery> meetingroomMapper;
	@Resource
    private ReservationorderMapper reservationorderMapper;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<Meetingroom> findListByParam(MeetingroomQuery param) {
		return this.meetingroomMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(MeetingroomQuery param) {
		return this.meetingroomMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<Meetingroom> findListByPage(MeetingroomQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<Meetingroom> list = this.findListByParam(param);
		PaginationResultVO<Meetingroom> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(Meetingroom bean) {
		return this.meetingroomMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<Meetingroom> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.meetingroomMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<Meetingroom> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.meetingroomMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(Meetingroom bean, MeetingroomQuery param) {
		StringTools.checkParam(param);
		return this.meetingroomMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(MeetingroomQuery param) {
		StringTools.checkParam(param);
		return this.meetingroomMapper.deleteByParam(param);
	}

	/**
	 * 根据RoomId获取对象
	 */
	@Override
	public Meetingroom getMeetingroomByRoomId(Integer roomId) {
		return this.meetingroomMapper.selectByRoomId(roomId);
	}

	/**
	 * 根据RoomId修改
	 */
	@Override
	public Integer updateMeetingroomByRoomId(Meetingroom bean, Integer roomId) {
		return this.meetingroomMapper.updateByRoomId(bean, roomId);
	}

	/**
	 * 根据RoomId删除
	 */
	@Override
	public Integer deleteMeetingroomByRoomId(Integer roomId) {
		return this.meetingroomMapper.deleteByRoomId(roomId);
	}

	/**
	 * 根据Name获取对象
	 */
	@Override
	public Meetingroom getMeetingroomByName(String name) {
		return this.meetingroomMapper.selectByName(name);
	}

	/**
	 * 根据Name修改
	 */
	@Override
	public Integer updateMeetingroomByName(Meetingroom bean, String name) {
		return this.meetingroomMapper.updateByName(bean, name);
	}

	/**
	 * 根据Name删除
	 */
	@Override
	public Integer deleteMeetingroomByName(String name) {
		return this.meetingroomMapper.deleteByName(name);
	}

	@Override
	public void updateStatus(MtroomDto mtroomDto) {
		Meetingroom room  =  this.meetingroomMapper.selectByRoomId(mtroomDto.getRoomId());
		room.setStatus(mtroomDto.getStatus());
		this.meetingroomMapper.updateByRoomId(room, mtroomDto.getRoomId());
	}

	@Override
	public OrderDto dispatchOrder(OrderDto orderDto) {
		MeetingroomQuery query = new MeetingroomQuery();
		query.setStatus(0);
		query.setCapacity(orderDto.getNum());
		query.setOrderBy("price_per_hour asc");
        List<Meetingroom> list = this.meetingroomMapper.selectList(query);
		if(list!=null && list.size()>0){
			orderDto.setRoomId(list.get(0).getRoomId());
			return orderDto;
		}
		List<Reservationorder> listReservationorder = reservationorderMapper.dispatchOrder(orderDto.getRoomId(),orderDto.getStartDate(),orderDto.getEndDate());
		if(listReservationorder==null || listReservationorder.size()==0){
			throw new BusinessException("没有合适的会议室，请重新下单");
		}
		for(Reservationorder order:listReservationorder){
			Meetingroom room =  this.meetingroomMapper.selectByRoomId(order.getRoomId());
			if(room.getCapacity()>=orderDto.getNum()){
				orderDto.setRoomId(order.getRoomId());
                return orderDto;
			}
		}
		throw new BusinessException("没有合适的会议室，请重新下单");

	}

	@Override
	public List<StatusVo> showStatus(Integer roomId, Date startDate, Date endDate) {
		List<StatusVo> result = new ArrayList<>();
		List<Reservationorder> list =  this.reservationorderMapper.selectLockStatus(roomId,startDate,endDate);
		if(list==null || list.size()==0){
			StatusVo vo = new StatusVo();
			vo.setStartTime(startDate);
			vo.setEndTime(endDate);
			vo.setStatus(0);
			result.add(vo);
			return result;
		}
		Date startDateTemp = startDate;
		for(Reservationorder order:list){
			startDate = startDateTemp;
			if(order.getCreatedAt().getTime()>startDate.getTime()){
				StatusVo vo = new StatusVo();
				vo.setStartTime(startDate);
				vo.setEndTime(order.getCreatedAt());
				vo.setStatus(0);
				result.add(vo);
				startDate = order.getCreatedAt();
			}
			if(order.getLockedUntil().getTime()<endDate.getTime()&& order.getLockedUntil().getTime()>startDate.getTime()){
				StatusVo vo = new StatusVo();
				vo.setStartTime(startDate);
				vo.setEndTime(order.getLockedUntil());
				vo.setStatus(1);
				result.add(vo);
                startDate = order.getLockedUntil();
			}else if(order.getLockedUntil().getTime()>=endDate.getTime()&& order.getLockedUntil().getTime()>startDate.getTime()){
				StatusVo vo = new StatusVo();
				vo.setStartTime(startDate);
				vo.setEndTime(endDate);
				vo.setStatus(1);
				result.add(vo);
				continue;
			}
			if(order.getStartTime().getTime()<endDate.getTime()&& order.getStartTime().getTime()>startDate.getTime()){
				StatusVo vo = new StatusVo();
				vo.setStartTime(startDate);
				vo.setEndTime(order.getStartTime());
				vo.setStatus(2);
				result.add(vo);
				startDate = order.getStartTime();
			}else if(order.getStartTime().getTime()>=endDate.getTime()&& order.getStartTime().getTime()>startDate.getTime()){
				StatusVo vo = new StatusVo();
				vo.setStartTime(startDate);
				vo.setEndTime(endDate);
				vo.setStatus(2);
				result.add(vo);
				continue;
			}
			if(order.getEndTime().getTime()<endDate.getTime()&& order.getEndTime().getTime()>startDate.getTime()){
				StatusVo vo = new StatusVo();
				vo.setStartTime(startDate);
				vo.setEndTime(order.getEndTime());
				vo.setStatus(3);
				result.add(vo);
				startDate = order.getEndTime();
			}else if(order.getEndTime().getTime()>=endDate.getTime()&&order.getEndTime().getTime()>startDate.getTime()){
				StatusVo vo = new StatusVo();
				vo.setStartTime(startDate);
				vo.setEndTime(endDate);
				vo.setStatus(3);
				result.add(vo);
			}

		}
		if(startDate.getTime()<endDate.getTime()){
			StatusVo vo = new StatusVo();
			vo.setStartTime(startDate);
			vo.setEndTime(endDate);
			vo.setStatus(0);
			result.add(vo);
		}
		return result;

	}
}